package lq1024;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
/*
lq1024
输入数据：
WoAiLanQiaoBeiDonatVyaCheslavLieseLotteAmphItriteCallIrrhoeBlanChefleurHoowAnnekaKeezhEekoni
输出：
AiAmphBlanChefleurHoowKeezh
 * */
public class Main {

	static ArrayList<String> names = new ArrayList<String>();
	static char[] name = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
	public static void main(String[] args) throws IOException {
		BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
		String s = read.readLine().trim();
		//读取全部名字
		readNames(s);
		
		/*
		//输出
		for(int i=0;i<names.size();i++) {
			System.out.printf("%s,",names.get(i));
		}
		System.out.println();
		*/
		
		/*
		//LIS，下标从0开始，lq1024部分用例不通过
		//len表示LIS长度
		int[] dp = new int[names.size()];
		int len = 0;
		for(int i=0;i<names.size();i++) {
			dp[i] = 1;
			for(int j=0;j<=i;j++) {
				if(names.get(j).compareTo(names.get(i))<0) {
					dp[i] = Math.max(dp[i], dp[j]+1);
				}
				if(dp[i]>len)
					len = dp[i];
			}
		}
		
		//逆向输出答案
		LinkedList<String> ans = new LinkedList<String>();
		for(int i=dp.length-1;i>=0;i--) {
			if(dp[i] == len) {
				ans.addFirst(names.get(i));
				len--;
			}else if(len == -1) {
				break;
			}
			
		}
		while(!ans.isEmpty()) {
			System.out.print(ans.pollFirst());
		}
		*/
		/*
		for(int i=0;i<dp.length;i++) {
			System.out.printf("[%s,%d],",names.get(i),dp[i]);
		}
		System.out.println();
		*/
		
		
		//LIS（二分优化）,下标从0开始，lq1024可AC
		String[] d = new String[names.size()];
		//names等长的整数数组，记录每个位置结尾的最大LIS值
		int[] lis = new int[names.size()];
		//LIS值，因为下标从0开始计算，所以实际LIS长度为len+1
		int len = 0;
		//初始化第一个元素
		d[0] = names.get(0);
		lis[0] = len;
		for(int i=1;i<names.size();i++) {
			//与前一个名字相等的情况
			if(names.get(i).compareTo(d[len]) == 0)
				continue;
			if(names.get(i).compareTo(d[len]) > 0) {
				//大于前一个名字的情况
				len++;
				d[len] = names.get(i);
				lis[i] = len;
			}else {
				//names.get(i)覆盖d中第一个大于或等于names.get(i)的数
				//二分查找
				int t = upperBound(0,len,names.get(i),d);
				d[t] = names.get(i);
				lis[i] = t;
			}
		}
		
		//逆向输出答案
		LinkedList<String> ans = new LinkedList<String>();
		for(int i=lis.length-1;i>=0;i--) {
			if(lis[i] == len) {
				ans.addFirst(names.get(i));
				len--;
			}else if(len == -1) {
				break;
			}
			
		}
		while(!ans.isEmpty()) {
			System.out.print(ans.pollFirst());
		}
		
		
		
		/*
		System.out.println(len+1);	
		
		for(int i=0;i<d.length;i++) {
			System.out.printf("%s,", d[i]);
		}
		System.out.println();
		for(int i=0;i<lis.length;i++) {
			System.out.printf("[%d,%s],", lis[i],names.get(i));
		}
		System.out.println();
		*/
		
	}
	
	
	
	static void readNames(String s) {
		//name下标p和读取游标i
		int p=0,i=0;
		while(i<s.length()) {
			//读入单词
			//重置下标p
			p = 0;
			//清空name
			name = new char[]{' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
			//存入大写首字母
			name[p] = s.charAt(i);
			i++;
			//循环读入小写字母直到输入结束或碰到大写
			while(i<s.length()&&(s.charAt(i)>='a'&&s.charAt(i)<='z')){
				//小写字母进入name
				p++;
				name[p] = s.charAt(i);
				i++;
			}
			names.add(String.valueOf(name).trim());
		}
	}
	
	// 找到第一个大于或等于target的元素的下标（注意区别，此题不是用标准LIS模板的二分部分）
	// 左开始下标l，右结束下标r，查询范围[l,r]
	static int upperBound(int l, int r, String target, String[] a) {
	    while(l <= r){
	        int mid = (l+r)/2;
	        if(target.compareTo(a[mid])>0){//注意不含等于的情况
	            l = mid + 1;
	        }else {
	            r = mid - 1;
	        }
	    }
	    return l;
	}
}
